package org.wangzhen.spring.event.springdemo;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.context.support.GenericApplicationContext;

/**
 * 添加Spring事件监听器的三种方式
 * 1、通过AnnotationConfigApplicationContext#addApplicationListener添加 事件监听器 context.addApplicationListener(new ApplicationListener<ApplicationEvent>()
 * 2、通过自定义事件监听器实现类，然后将具体实现类当做一个bean注册到spring 上下文中； static class MyApplicationEventListener implements ApplicationListener
 * 3、通过@EventListener 注解的方式，实现事件的监听
 *
 * 备注：
 * 1、通过打印的1、2、3、4、5来观察事件执行的先后顺序
 * 2、为什么@EventListener 事件监听的方式最先执行，
 * 3、方式一和方式二，其实差不太多
 *      （一个是匿名实现方式/一个是具体实现类，
 *        一个是通过ApplicationContext#addApplicationListener方式，一个是通过register作为一个配置类的方式来实现）
 */
public class ApplicationListerenDemo implements ApplicationEventPublisherAware {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

        context.register(ApplicationListerenDemo.class);

        System.out.println("111111111111111");
        // 方法一、基于spring接口（ConfigurableApplicationContext）向spring上下文注册事件监听器
        context.addApplicationListener(event -> {
            // 打印接收到的事件
            System.out.println("接口的方式："+event);
        });

        // 方式二：把自定义的spring listener监听器作为一个Bean 注册到spring
        context.register(MyApplicationEventListener.class);

        System.out.println("22222222222222222");
        context.refresh();
        System.out.println("33333333333333333");
        context.start();
        System.out.println("44444444444444444");
        context.stop();
        System.out.println("55555555555555555");
        context.close();
        System.out.println("66666666666666666");
    }

    /**
     * 在回调注入ApplicationEventPublisher的方法里面直接，发送事件
     * @param applicationEventPublisher
     */
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        // 发送ApplicationEvent事件
        applicationEventPublisher.publishEvent(new ApplicationEvent("hello 中国") {
        });
        // 发送PayloadApplicationEvent 事件
        applicationEventPublisher.publishEvent("hello 北京");
    }

    static class MyApplicationEventListener implements ApplicationListener {
        @Override
        public void onApplicationEvent(ApplicationEvent event) {
            System.out.println("自定义监听器: "+event);
        }
    }

    // 方式三：通过@EventListener的方式来实现事件监听
    @EventListener
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("@EventListeren :"+ event);
    }
}
